package com.spider.silence.pool;

import com.google.common.collect.Lists;
import com.spider.silence.downloader.SinaSiChuanDownLoader;
import com.spider.silence.utils.PropertiesUtil;
import org.apache.log4j.Logger;


import java.lang.reflect.InvocationTargetException;
import java.util.LinkedList;

/**
 * Created by Linbo Hu on 2017/6/20.
 * 新浪四川爬虫下载器池
 */
public class SinaSiChuanDownLoaderPool {

    private Logger logger =Logger.getLogger(SinaSiChuanDownLoader.class);

    private static final SinaSiChuanDownLoaderPool INSTANCE = new SinaSiChuanDownLoaderPool();

    private LinkedList<SinaSiChuanDownLoader> pool = Lists.newLinkedList();

    //初始化下载器池
    private SinaSiChuanDownLoaderPool() {
        logger.info("初始化新浪四川下载池");
        int initNum= Integer.parseInt(PropertiesUtil.getVal("SinaSiChuan.DownLoader.Pool.initNum"));
        SinaSiChuanDownLoader sinaSiChuanDownLoader = new SinaSiChuanDownLoader();
        //sinaSiChuanDownLoader.init();
        for(int i = 0; i < initNum; i++) {
            SinaSiChuanDownLoader temp = null;
            synchronized(pool) {
                try {
                    temp = sinaSiChuanDownLoader.cloneDownLoader();
                    pool.add(temp);
                    pool.notifyAll();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                    logger.error(e);
                } catch (NoSuchMethodException e) {
                    e.printStackTrace();
                    logger.error(e);
                } catch (InstantiationException e) {
                    e.printStackTrace();
                    logger.error(e);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                    logger.error(e);
                }
            }
        }
    }

    public static SinaSiChuanDownLoaderPool getInstance() {
        return INSTANCE;
    }


    /**
     * 获取一个下载器
     * @param mills
     * @return
     * @throws InterruptedException
     */
    public SinaSiChuanDownLoader fetchDownLoader(long mills) throws InterruptedException {
        synchronized(pool) {
            if(mills <= 0) {
                while(pool.isEmpty()) {
                    pool.wait();
                }
                return pool.removeFirst();
            } else {
                long future = System.currentTimeMillis() + mills;
                long remaining = mills;
                while (pool.isEmpty() && remaining > 0) {
                    pool.wait(remaining);
                    remaining = future - System.currentTimeMillis();
                }
                SinaSiChuanDownLoader sinaSiChuanDownLoader = null;
                if(!pool.isEmpty()) {
                    sinaSiChuanDownLoader = pool.removeFirst();
                }
                return sinaSiChuanDownLoader;
            }
        }
    }



    /**
     * 释放一个下载器
     * @param sinaSiChuanDownLoader
     */
    public void releaseDownLoader(SinaSiChuanDownLoader sinaSiChuanDownLoader) {
        if(sinaSiChuanDownLoader != null) {
            synchronized (pool) {
                pool.addLast(sinaSiChuanDownLoader);
                pool.notifyAll();
            }
        }
    }



}
